#include <iostream>
#include <vector>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#include <cstring>
#include <mutex>
#include <thread>

// 互斥锁用于保护 socketList
std::mutex socketListMutex;

// 创建 TCP socket 并绑定、监听指定端口
int createSocket(int port) {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        std::cerr << "创建 socket 失败: " << strerror(errno) << std::endl;
        return -1;
    }

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(port);

    if (bind(sockfd, reinterpret_cast<sockaddr*>(&serverAddr), sizeof(serverAddr)) == -1) {
        std::cerr << "绑定 socket 失败: " << strerror(errno) << std::endl;
        close(sockfd);
        return -1;
    }

    if (listen(sockfd, SOMAXCONN) == -1) {
        std::cerr << "监听 socket 失败: " << strerror(errno) << std::endl;
        close(sockfd);
        return -1;
    }

    std::cout << "正在监听端口 " << port << std::endl;
    return sockfd;
}

// 使用 select 监听多个 socket，并处理事件
void selectAndHandleSockets(std::vector<int>& socketList) {
    fd_set readfds;
    int maxFd = 0;

    while (true) {
        {
            std::lock_guard<std::mutex> lock(socketListMutex);
            FD_ZERO(&readfds);
            maxFd = 0;
            for (int sock : socketList) {
                if (sock != -1) {
                    FD_SET(sock, &readfds);
                    if (sock > maxFd) {
                        maxFd = sock;
                    }
                }
            }
        }

        timeval timeout;
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        int activity = select(maxFd + 1, &readfds, nullptr, nullptr, &timeout);
        if (activity == -1) {
            std::cerr << "select 调用出错: " << strerror(errno) << std::endl;
        } else if (activity == 0) {
            std::cout << "select 超时，未检测到事件" << std::endl;
        } else {
            std::lock_guard<std::mutex> lock(socketListMutex);
            for (int sock : socketList) {
                if (sock != -1 && FD_ISSET(sock, &readfds)) {
                    sockaddr_in clientAddr;
                    socklen_t clientAddrLen = sizeof(clientAddr);
                    int newSocket = accept(sock, reinterpret_cast<sockaddr*>(&clientAddr), &clientAddrLen);
                    if (newSocket == -1) {
                        std::cerr << "接受连接失败: " << strerror(errno) << std::endl;
                    } else {
                        char clientIP[INET_ADDRSTRLEN];
                        inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);
                        std::cout << "接受来自 " << clientIP << ":" << ntohs(clientAddr.sin_port) << " 的连接" << std::endl;
                        close(newSocket);
                    }
                }
            }
        }
    }
}

// 动态添加 socket 的函数
void addSocket(std::vector<int>& socketList, int port) {
    int sock = createSocket(port);
    if (sock != -1) {
        std::lock_guard<std::mutex> lock(socketListMutex);
        socketList.push_back(sock);
    }
}

int main() {
    std::vector<int> socketList;

    // 创建初始 socket 并添加到监听列表
    int sock1 = createSocket(8080);
    if (sock1 != -1) {
        socketList.push_back(sock1);
    }

    // 启动一个线程来运行 select 监听
    std::thread selectThread(selectAndHandleSockets, std::ref(socketList));

    // 动态添加另一个 socket 到监听列表
    addSocket(socketList, 8081);

    // 模拟持续动态添加 socket
    for (int i = 8082; i < 8085; ++i) {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        addSocket(socketList, i);
    }

    // 等待 select 线程结束（这里不会结束，因为是无限循环）
    selectThread.join();

    // 关闭所有 socket
    {
        std::lock_guard<std::mutex> lock(socketListMutex);
        for (int sock : socketList) {
            if (sock != -1) {
                close(sock);
            }
        }
    }

    return 0;
}    